ao Module 
version: 0.0.3
ao process communication is handled by messages, each process receives messages in the form of ANS-104 DataItems, and needs to be able to do the following common operations.
- ao.send(msg) - send message to another process
- ao.spawn(module, msg) - spawn a process
The goal of this library is to provide this core functionality in the box of the ao developer toolkit. As a developer you have the option to leverage this library or not, but it integrated by default.
Properties 
| Name | Description | Type | 
|---|---|---|
| id | Process Identifier (TxID) | string | 
| _module | Module Identifier (TxID) | string | 
| authorities | Set of Trusted TXs | string | 
| Authority | Identifiers that the process is able to accept transactions from that are not the owner or the process (0-n) | string | 
| _version | The version of the library | string | 
| reference | Reference number of the process | number | 
| env | Evaluation Environment | object | 
| outbox | Holds Messages and Spawns for response | object | 
| assignables | List of assignables of the process | list | 
| nonExtractableTags | List of non-extractable tags of the process | list | 
| nonForwardableTags | List of non-forwardable tags of the process | list | 
| init | Initializes the AO environment | function | 
| send | Sends a message to a target process | function | 
| assign | Assigns a message to the process | function | 
| spawn | Spawns a process | function | 
| result | Returns the result of a message | function | 
| isTrusted | Checks if a message is trusted | function | 
| isAssignment | Checks if a message is an assignment | function | 
| isAssignable | Checks if a message is assignable | function | 
| addAssignable | Adds an assignable to the assignables list | function | 
| removeAssignable | Removes an assignable from the assignables list | function | 
| clearOutbox | Clears the outbox | function | 
| normalize | Normalizes a message by extracting tags | function | 
| sanitize | Sanitizes a message by removing non-forwardable tags | function | 
| clone | Clones a table recursively | function | 
Environment Schema 
The ao.env variable contains information about the initializing message of the process. It follows this schema:
ao.env = {
  Process = {
    Id = string,      -- Process ID
    Owner = string,   -- Process owner
    TagArray = {      -- Array of name-value pairs
      { name = string, value = string }
    },
    Tags = {          -- Tags as key-value pairs
      [string] = string
    }
  }
}Example 
{
  Process = {
    Id = "A1b2C3d4E5f6G7h8I9j0K1L2M3N4O5P6Q7R8S9T0",
    Owner = "Xy9PqW3vR5sT8uB1nM6dK0gF2hL4jC7iE9rV3wX5",
    TagArray = {
      { name = "App-Name", value = "aos" }
    },
    Tags = {
      ["App-Name"] = "aos"
    }
  }
}Methods 
ao.send(msg: Message) 
Takes a Message as input. The function adds ao-specific tags and stores the message in ao.outbox.Messages.
Example 
local message = ao.send({
    Target = msg.From,
    Data = "ping",
    Tags = {
        ["Content-Type"] = "text/plain",
        ["Action"] = "Ping"
    }
})
-- or
local message = ao.send({
    Target = msg.From,
    Data = "ping",
    Action = "Ping",               -- will be converted to Tags
    ["Content-Type"] = "text/plain"  -- will be converted to Tags
})ao.spawn(module: string, spawn: Spawn) 
Takes a module ID string and Spawn as input. Returns a Spawn table with a generated Ref_ tag.
Example 
local process = ao.spawn("processId", {
    Data = { initial = "state" },
    Tags = {
        ["Process-Type"] = "calculator"
    }
})ao.assign(assignment: Assignment) 
Takes an Assignment as input. Adds the assignment to ao.outbox.Assignments.
Example 
ao.assign({
    Processes = {"process-1", "process-2"},
    Message = "sample-message-id"
})ao.result(result: Result) 
Takes a Result as input. Returns the final process execution result.
Example 
local process_result = ao.result({
    Output = "Process completed successfully",
    Messages = {
        { Target = "ProcessY", Data = "Result data", Tags = { ["Status"] = "Success" } }
    },
    Spawns = { "spawned-process-1" },
    Assignments = { {Processes = { "process-1" }, Message = "assignment-message-id"} }
})ao.isAssignable(msg: Message) 
Takes a Message as input. Returns true if the message matches a pattern in ao.assignables.
Example 
local can_be_assigned = ao.isAssignable({
    Target = "ProcessA",
    Data = "Some content",
    Tags = {
         ["Category"] = "Info"
    }
})ao.isAssignment(msg: Message) 
Takes a Message as input. Returns true if the message is assigned to a different process.
Example 
local is_assigned_elsewhere = ao.isAssignment({
    Target = "AnotherProcess"
})ao.addAssignable(name: string, condition: function) 
Adds a named condition function to the process's list of assignables. Messages matching any condition will be accepted when assigned.
Note: The
conditionparameter uses a similar pattern matching approach as thepatternparameter inHandlers.add(). For more advanced pattern matching techniques, see the Handlers Pattern Matching documentation.
Example 
-- Allow transactions from ArDrive
ao.addAssignable("allowArDrive", function (msg)
    return msg.Tags["App-Name"] == "ArDrive-App"
end)
-- Allow transactions with specific content type
ao.addAssignable("allowJson", function (msg)
    return msg.Tags["Content-Type"] == "application/json"
end)ao.removeAssignable(name: string) 
Removes a previously added assignable condition from the process's list of assignables.
Example 
ao.removeAssignable("allowArDrive")ao.isTrusted(msg: Message) 
Takes a Message as input. Returns true if the message is from a trusted source.
Example 
if ao.isTrusted(msg) then
    -- Process trusted message
else
    -- Handle untrusted message
endCustom ao Table Structures 
Tags 
Used by: ao.send(), ao.spawn(), ao.normalize(), ao.sanitize()
All of the below syntaxes are valid, but each syntax gets converted to { name = string, value = string } tables behind the scenes. We use alternative 1 throughout the documentation for brevity and consistency.
-- Default: Array of name-value pair tables
Tags = {
    { name = "Content-Type", value = "text/plain" },
    { name = "Action", value = "Ping" }
}
-- Alternative 1: Direct key-value pairs in Tags table using string keys
Tags = {
    ["Content-Type"] = "text/plain",
    ["Action"] = "Ping"
}
-- Alternative 2: Direct key-value pairs in Tags table using dot notation
Tags = {
    Category = "Info",
    Action = "Ping"
}Root-level Tag Conversion
Any keys in the root message object that are not one of: Target, Data, Anchor, Tags, or From will automatically be converted into Tags using the key as the tag name and its value as the tag value.
-- These root-level keys will be automatically converted to Tags
{
    Target = "process-id",
    Data = "Hello",
    ["Content-Type"] = "text/plain",  -- Will become a Tag
    Action = "Ping"                   -- Will become a Tag
}Message 
Used by: ao.send(), ao.isTrusted(), ao.isAssignment(), ao.isAssignable(), ao.normalize(), ao.sanitize()
-- Message structure
{
    Target = string,     -- Required: Process/wallet address
    Data = any,          -- Required: Message payload
    Tags = Tag<table>
}Spawn 
Used by: ao.spawn()
-- Spawn structure
{
    Data = any,          -- Required: Initial process state
    Tags = Tag<table>    -- Required: Process tags
}Assignment 
Used by: ao.assign(), ao.result()
-- Assignment configuration table structure
{
    Processes = { string }, -- Required: List of target process ID strings
    Message = string       -- Required: Message to assign
}Result 
Used by: ao.result()
-- Process result structure
{
    Output = string,           -- Optional: Process output
    Messages = Message<table>,   -- Optional: Generated messages
    Spawns = Spawn<table>,        -- Optional: Spawned processes
    Assignments = Assignment<table>,    -- Optional: Process assignments
    Error = string         -- Optional: Error information
}